﻿using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Rhino.Mocks;
using TSVNAddin.SVN;
using EnvDTE;
using EnvDTE80;

namespace TSVNAddin.Core.Test
{
	[TestFixture]
	public class WorkingContextFixture
	{
		[Test]
		public void GetWorkingRoot()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\myproject\trunk\myproject.sln");

			var versionControl = MockRepository.GenerateMock<IVersionControl>();
			versionControl.Expect(x => x.Contains(@"c:\svnroot\myproject\trunk\")).Return(true);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);
			string workingRoot = workingContext.GetWorkingRoot();

			Assert.AreEqual(@"c:\svnroot\myproject\trunk\", workingRoot);
			versionControl.VerifyAllExpectations();
		}

		[Test]
		public void GetWorkingRootShouldReturnSolutionFolderWhenWorkingCopyNotFound()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\myproject\trunk\myproject.sln");

			var versionControl = MockRepository.GenerateMock<IVersionControl>();
            versionControl.Expect(x => x.Contains(@"c:\svnroot\myproject\trunk\")).Return(false);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);
			string workingRoot = workingContext.GetWorkingRoot();

			Assert.AreEqual(@"c:\svnroot\myproject\trunk\", workingRoot);
			versionControl.VerifyAllExpectations();
		}

		[Test]
		public void GetWorkingRootReturnLastRootFoundIfSolutionFileNameNoChanged()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\myproject\trunk\myproject.sln");

			var versionControl = MockRepository.GenerateMock<IVersionControl>();
            versionControl.Expect(x => x.Contains(@"c:\svnroot\myproject\trunk\")).Return(true).Repeat.Once();

			WorkingContext workingContext = new WorkingContext(solution, versionControl);

			string root1 = workingContext.GetWorkingRoot();
			string root2 = workingContext.GetWorkingRoot();

            Assert.AreEqual(@"c:\svnroot\myproject\trunk\", root1);
            Assert.AreEqual(@"c:\svnroot\myproject\trunk\", root2);

			versionControl.VerifyAllExpectations();
		}

		[Test]
		public void GetWorkingRootRenewWorkingCopyWhenResetCalls()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\myproject\trunk\myproject.sln");

			var versionControl = MockRepository.GenerateMock<IVersionControl>();
            versionControl.Expect(x => x.Contains(@"c:\svnroot\myproject\trunk\")).Return(true).Repeat.Times(2);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);

			string root1 = workingContext.GetWorkingRoot();
			workingContext.ResetWorkingCopy();
			string root2 = workingContext.GetWorkingRoot();

            Assert.AreEqual(@"c:\svnroot\myproject\trunk\", root1);
            Assert.AreEqual(@"c:\svnroot\myproject\trunk\", root2);

			versionControl.VerifyAllExpectations();
		}

		[Test]
		public void GetWorkingRootReturnnSolutionFolderWhenNewFileNameHasNoWorking()
		{
			var versionControl = MockRepository.GenerateStub<IVersionControl>();
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);

			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\myproject\trunk\myproject.sln").Repeat.Once();
            versionControl.Expect(x => x.Contains(@"c:\svnroot\myproject\trunk\")).Return(true);

			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\myproject\trunk2\myproject2.sln");
            versionControl.Stub(x => x.Contains(@"c:\svnroot\myproject\trunk2\")).Return(false);
            versionControl.Stub(x => x.Contains(@"c:\svnroot\myproject\")).Return(false);
            versionControl.Stub(x => x.Contains(@"c:\svnroot\")).Return(false);
            versionControl.Stub(x => x.Contains(@"c:\")).Return(false);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);

			string root1 = workingContext.GetWorkingRoot();
			string root2 = workingContext.GetWorkingRoot();
			string root3 = workingContext.GetWorkingRoot();

            Assert.AreEqual(@"c:\svnroot\myproject\trunk\", root1);
			Assert.AreEqual(@"c:\svnroot\myproject\trunk2\", root2);
			Assert.AreEqual(@"c:\svnroot\myproject\trunk2\", root3);
		}

		[Test]
		public void SetWorkingRoot()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\myproject\trunk\myproject.sln");

			var versionControl = MockRepository.GenerateMock<IVersionControl>();
			versionControl.Stub(x => x.Contains(@"c:\svnroot\myproject\trunk\")).Return(true);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);

			Assert.AreEqual(@"c:\svnroot\myproject\trunk\", workingContext.GetWorkingRoot()); 

			workingContext.SetWorkingRoot(@"c:\myroot\");

			Assert.AreEqual(@"c:\myroot\", workingContext.GetWorkingRoot());
		}

		[Test]
		public void CanExecutePathCommandsWhenSolutionIsOpenedAndWorkingRootExists()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svn\myproject\trunk\file.txt");
			solution.Stub(x => x.IsOpen()).Return(true);

			var versionControl = MockRepository.GenerateMock<IVersionControl>();
            versionControl.Stub(x => x.Contains(@"c:\svn\myproject\trunk\")).Return(true);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);
			bool confirm = workingContext.CanExecutePathCommands();

			Assert.IsTrue(confirm);
		}

		[Test]
		public void CanNotExecutePathCommandsWhenSolutionIsClosed()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.IsOpen()).Return(false);

			WorkingContext workingContext = new WorkingContext(solution, null);
			bool confirm = workingContext.CanExecutePathCommands();

			Assert.IsFalse(confirm);
		}

		[Test]
		public void CanNotExecutePathCommandsWhenNotExistsSVNInfo()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svn\myproject\trunk\file.txt");
			solution.Stub(x => x.IsOpen()).Return(true);

			var versionControl = MockRepository.GenerateMock<IVersionControl>();
			versionControl.Stub(x => x.Contains(@"c:\svn\myproject\trunk\")).Return(false);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);
			bool confirm = workingContext.CanExecutePathCommands();

			Assert.IsFalse(confirm);
		}

		[Test]
		public void DoesNotContainsFileWhenworkingContextIsNotActive()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.IsOpen()).Return(false);

			WorkingContext workingContext = new WorkingContext(solution, null);
			bool contains = workingContext.CanExecuteCommandsOnPath(@"c:\svn\myproject\trunk\file.txt");

			Assert.IsFalse(contains);
		}

		[Test]
		public void DoesNotContainsFileWhenPathDoesntMatch()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\test.sln");
			solution.Stub(x => x.IsOpen()).Return(true);

			var versionControl = MockRepository.GenerateStub<IVersionControl>();
            versionControl.Stub(x => x.Contains(@"c:\svnroot\")).Return(true);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);
			bool contains = workingContext.CanExecuteCommandsOnPath(@"c:\svnroot2\trunk\file.txt");

			Assert.IsFalse(contains);
		}

		[Test]
		public void ContainsFileWhenCanExecutePathCommandsAndPathMatch()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\test.sln");
			solution.Stub(x => x.IsOpen()).Return(true);

			var versionControl = MockRepository.GenerateStub<IVersionControl>();
            versionControl.Stub(x => x.Contains(@"c:\svnroot\")).Return(true);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);
			bool contains = workingContext.CanExecuteCommandsOnPath(@"c:\SvnRoot\Trunk\file.txt");

			Assert.IsTrue(contains);
		}

		[Test]
		public void ContainsFileWhenCanExecutePathCommandsAndPathMatch2()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"C:\svnroot\test.sln");
			solution.Stub(x => x.IsOpen()).Return(true);

			var versionControl = MockRepository.GenerateStub<IVersionControl>();
			versionControl.Stub(x => x.Contains(@"C:\svnroot\")).Return(true);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);
			bool contains = workingContext.CanExecuteCommandsOnPath(@"c:\SvnRoot\Trunk\file.txt");

			Assert.IsTrue(contains);
		}

		[Test]
		public void CanExecuteCheckout()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.GetFileName()).Return(@"c:\svnroot\myproject\trunk\myproject.sln");
			solution.Stub(x => x.IsOpen()).Return(true);

			var versionControl = MockRepository.GenerateStub<IVersionControl>();
            versionControl.Stub(x => x.Contains(@"c:\svn\myproject\trunk\")).IgnoreArguments().Return(false);

			WorkingContext workingContext = new WorkingContext(solution, versionControl);
			bool confirm = workingContext.CanExecuteCheckout();

			Assert.IsTrue(confirm);
		}

		[Test]
		public void CanNotExecuteCheckoutWhenSolutionIsNotOpen()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.IsOpen()).Return(false);

			WorkingContext workingContext = new WorkingContext(solution, null);
			bool confirm = workingContext.CanExecuteCheckout();

			Assert.IsFalse(confirm);
		}

		[Test]
		public void CanSetWorkingRoot()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.IsOpen()).Return(false);

			WorkingContext workingContext = new WorkingContext(solution, null);
			bool confirm = workingContext.CanSetWorkingRoot();

			Assert.IsFalse(confirm);
		}

		[Test]
		public void CanNotSetWorkingRoot()
		{
			var solution = MockRepository.GenerateMock<SolutionAdapter>((DTE2)null);
			solution.Stub(x => x.IsOpen()).Return(true);

			WorkingContext workingContext = new WorkingContext(solution, null);
			bool confirm = workingContext.CanSetWorkingRoot();

			Assert.IsTrue(confirm);
		}
	}
}
